#include "qcw_analogclock.h"
#include <QTime>
#include <QTimer>
#include <QPainter>
#include <QtCore/qmath.h>

QcwAnalogClock::QcwAnalogClock(QWidget *parent): QWidget(parent)
{
	m_crownColor = Qt::blue;
	m_foreground = Qt::green;
	m_background = Qt::black;
	m_hourHandColor = QColor(255,215,0);
	m_minHandColor = QColor(255,215,0);
	m_secHandColor = QColor(255,215,0);
	m_numericIndicatorEnabled = true;
	
	QTimer *timer = new QTimer(this);
	connect(timer, SIGNAL(timeout()), this, SLOT(update()));
	timer->start(1000);
	
	resize(100, 100);
}

void QcwAnalogClock::paintEvent(QPaintEvent *)
{
	QPainter painter(this);
	painter.setRenderHint(QPainter::Antialiasing); 	/* 使用反锯齿(如果可用) */
	painter.translate(width() / 2, height() / 2);	/* 坐标变换为窗体中心 */
	int side = qMin(width(), height());
	painter.scale(side / 200.0, side / 200.0);		/* 比例缩放 */
	painter.setPen(Qt::NoPen);
	
	drawCrown(&painter);
	drawBackground(&painter);
	drawScale(&painter);
	drawScaleNum(&painter);
	drawIndicator(&painter);
	
	if (m_numericIndicatorEnabled)					/* 数字显示 */
		drawNumericValue(&painter);
}

void QcwAnalogClock::drawCrown(QPainter *painter)
{
	painter->save();
	painter->setPen(QPen(m_crownColor, 3));
	painter->drawEllipse(-95, -95, 190, 190);
	painter->restore();
}

void QcwAnalogClock::drawBackground(QPainter *painter)
{
	painter->save();
	painter->setBrush(m_background);
	painter->drawEllipse(-92, -92, 184, 184);
	painter->restore();
}

void QcwAnalogClock::drawScale(QPainter *painter)
{
	painter->save();
	painter->setPen(m_foreground);
	QPen pen = painter->pen();
	for (int i = 0; i <= 60; i++)
	{
		if (i % 5 == 0)
		{
			pen.setWidth(1);
			painter->setPen(pen);
			painter->drawLine(0, 80, 0, 90);
		}
		else
		{
			pen.setWidth(0);
			painter->setPen(pen);
			painter->drawLine(0, 85, 0, 90);
		}
		painter->rotate(6);
	}
	painter->restore();	
}

void QcwAnalogClock::drawScaleNum(QPainter *painter)
{
	painter->save();
	painter->setPen(m_foreground);
	double startRad = 60 * (3.14 / 180);
	double deltaRad = 30 * (3.14 / 180);
	double sina,cosa;
	int x, y;
	QFontMetricsF fm(this->font());
	double w, h;
	QString str;
	
	for (int i = 0; i < 12; i++)
	{
		sina = sin(startRad - i * deltaRad);
		cosa = cos(startRad - i * deltaRad);
		
		str = QString( "%1" ).arg(i + 1);
		w = fm.size(Qt::TextSingleLine,str).width();
		h = fm.size(Qt::TextSingleLine,str).height();
		x = 70 * cosa - w / 2;
		y = -70 * sina + h / 4;	
		painter->drawText(x, y, str);
	}		
	painter->restore();	
}

void QcwAnalogClock::drawIndicator(QPainter *painter)
{	
	QTime time = QTime::currentTime();
	QPolygon pts;
	
	painter->save();
	pts.setPoints(4, -3,8, 3,8, 2,-40, -2,-40);	/* 时针 */
	painter->rotate(30.0 * ((time.hour() + time.minute() / 60.0)));
	painter->setBrush(m_hourHandColor);
	painter->drawConvexPolygon(pts);
	painter->restore();
	
	painter->save();
	pts.setPoints(4, -2,8, 2,8, 1,-60, -1,-60);	/* 分针 */
	painter->rotate(6.0 * (time.minute() + time.second() / 60.0));
	painter->setBrush(m_minHandColor);
	painter->drawConvexPolygon(pts);
	painter->restore();
	
	painter->save();
	pts.setPoints(3, -1,10, 1,10, 0,-70);	/* 秒针 */
	painter->rotate(6.0 * time.second());
	painter->setBrush(m_secHandColor);
	painter->drawConvexPolygon(pts);
	painter->restore();
	
	// draw indicator hat
	painter->save();
	QColor niceBlue(150, 150, 200);
	QConicalGradient coneGradient(0, 0, -90.0);
    coneGradient.setColorAt(0.0, Qt::darkRed);
    coneGradient.setColorAt(0.2, Qt::red);
    coneGradient.setColorAt(0.5, Qt::red);
    coneGradient.setColorAt(1.0, Qt::darkRed);
    painter->setPen(Qt::NoPen);
    painter->setBrush(coneGradient);
    painter->drawEllipse(-5, -5, 10, 10);
	painter->restore();
}

void QcwAnalogClock::drawNumericValue(QPainter *painter)
{	 
	QTime time = QTime::currentTime();
	
	painter->save();
	painter->setBrush(Qt::blue);
	painter->drawRect(-30, 30, 60, 14);
	
	QString str  =  QString("%1:%2:%3").arg(time.hour(), 2, 10, QLatin1Char('0')).arg(time.minute(), 2, 10, QLatin1Char('0')).arg(time.second(), 2, 10, QLatin1Char('0'));
	QFontMetricsF fm(font());
	double w = fm.size(Qt::TextSingleLine, str).width();
	painter->setPen(Qt::black);
	painter->drawText(-w / 2, 42, str);
	painter->restore();
}

void QcwAnalogClock::setCrownColor(QColor newColor)
{
	m_crownColor = newColor;
	update();
}

void QcwAnalogClock::setForeground(QColor newForeColor)
{
	m_foreground = newForeColor;
	update();
}

void QcwAnalogClock::setBackground(QColor newBackColor)
{
	m_background = newBackColor;
	update();
}

void QcwAnalogClock::setHourHandColor(QColor color)
{
	m_hourHandColor = color;
	update();
}

void QcwAnalogClock::setMinHandColor(QColor color)
{
	m_minHandColor = color;
	update();
}

void QcwAnalogClock::setSecHandColor(QColor color)
{
	m_secHandColor = color;
	update();
}

void QcwAnalogClock::setNumericIndicatorEnabled(bool enable)
{
	m_numericIndicatorEnabled = enable;
	update();
}
